home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998…eptember: Technology Seed / September 98 ADC Seed CD.toast / FireWire 1.1 DR2 SDK / Source / AVTransport / AVTransportFamily / AVTransportFamily.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-15  |  26.5 KB  |  1,072 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        AVTransportFamily.c
  3.  
  4.     Contains:    Services provided by the AV transport control driver family.
  5.  
  6.     Written by:    Erik Staats
  7.  
  8.     Copyright:    © 1996-1997 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.        <FW7>     3/18/97    ES        Changed to not create new AVT driver if we get device added
  13.                                     notification for a device we already have in our device list.
  14.        <FW6>      2/7/97    ES        Removed calls to AESendSystemEvent. Added equivalent
  15.                                     implementation. Added GetNextAVTClientEvent.
  16.        <FW5>    10/22/96    ES        Changed to use generic driver model. Changed to use Generic
  17.                                     Driver Family notification rather than DevNLib notification.
  18.        <FW4>      8/1/96    ES        Took out unused local variables.
  19.        <FW3>     6/27/96    ES        Took out include of AdminMessagePort.h.
  20.        <FW2>     6/20/96    ES        Filled in contains and written by fields.
  21.        <FW1>     6/20/96    ES        first checked in
  22.  
  23. */
  24.  
  25. #include <Types.h>
  26. #include <Errors.h>
  27. #include <Strings.h>
  28. #include <Traps.h>
  29. #include <Events.h>
  30. #include <AppleEvents.h>
  31. #include <Devices.h>
  32. #include <CodeFragments.h>
  33. #include <DriverServices.h>
  34. #include <NameRegistry.h>
  35. #include <GenericDriverFamily.h>
  36. #include <AVTransport.h>
  37. #include <AVTransportPriv.h>
  38. #include <AVTransportExpert.h>
  39.  
  40. ////////////////////////////////////////////////////////////////////////////////
  41. //
  42. // Define global structure to hold all of the AV transport control driver
  43. // Family data.
  44. //
  45.  
  46. AVTFamilyDataPtr                gpAVTFamilyData = nil;
  47. AVTExpertDataPtr                gpAVTExpertData = nil;
  48.  
  49.  
  50. ////////////////////////////////////////////////////////////////////////////////
  51. //
  52. // Internal routine prototypes.
  53. //
  54.  
  55. static OSStatus    AVTEventHandler (
  56.     GDFDeviceEventDataPtr        pGDFDeviceEventData);
  57.  
  58. static OSStatus    AVTHandleDeviceAdded (
  59.     GDFDeviceEventDataPtr        pGDFDeviceEventData);
  60.  
  61. static OSStatus    AVTHandleDeviceRemoved (
  62.     GDFDeviceEventDataPtr        pGDFDeviceEventData);
  63.  
  64. static OSErr    AVTSendClientAppleEvent (
  65.     AVTClientDataPtr            pAVTClientData,
  66.     const AppleEvent            *theAppleEvent,
  67.     AESendMode                    sendMode,
  68.     AESendPriority                sendPriority,
  69.     long                        timeOutInTicks,
  70.     AEIdleUPP                    idleProc,
  71.     AEFilterUPP                    filterProc);
  72.  
  73. static void    DisposeClientAppleEventData (
  74.     ClientAppleEventDataPtr        pClientAppleEventData);
  75.  
  76. static OSStatus    AVTCreateClientAppleEventQueue (
  77.     AVTClientDataPtr            pAVTClientData);
  78.  
  79. static OSStatus    AVTDisposeClientAppleEventQueue (
  80.     AVTClientDataPtr            pAVTClientData);
  81.  
  82. static OSStatus    AVTAddDriver (
  83.     GDFDeviceEventDataPtr        pGDFDeviceEventData,
  84.     AVTDriverID                    *pAVTDriverID);
  85.  
  86. static OSStatus    CreateAVTDriverID (
  87.     AVTDriverID                    *pAVTDriverID);
  88.  
  89. static void    DisposeAVTDriver (
  90.     AVTDriverID                    avtDriverID);
  91.  
  92. static AVTDriverID    AVTFindDriver (
  93.     RegEntryIDPtr                pRegEntryID);
  94.  
  95.  
  96. ////////////////////////////////////////////////////////////////////////////////
  97. ////////////////////////////////////////////////////////////////////////////////
  98. //
  99. // Public routines.
  100. //
  101. ////////////////////////////////////////////////////////////////////////////////
  102. ////////////////////////////////////////////////////////////////////////////////
  103.  
  104. ////////////////////////////////////////////////////////////////////////////////
  105. //
  106. // RegisterAVTClientApplication
  107. //
  108. //   This routine registers the calling application as a client of the
  109. // AV transport control driver family.
  110. //
  111.  
  112. OSStatus    RegisterAVTClientApplication(
  113.     AVTClientID                    *pAVTClientID,
  114.     UInt32                        clientContextData)
  115. {
  116.     AVTClientID                    avtClientID = kInvalidAVTClientID;
  117.     AVTClientDataPtr            pAVTClientData = nil,
  118.                                 pNextAVTClientData;
  119.     ProcessSerialNumber            currentPSN;
  120.     OSStatus                    status = noErr;
  121.  
  122.     // Allocate client data record.
  123.     pAVTClientData =
  124.         (AVTClientDataPtr) PoolAllocateResident (sizeof (AVTClientData), true);
  125.     if (pAVTClientData != nil)
  126.     {
  127.         pAVTClientData->clientContextData = clientContextData;
  128.         avtClientID = (AVTClientID) pAVTClientData;
  129.     }
  130.     else
  131.     {
  132.         status = memFullErr;
  133.     }
  134.  
  135.     // Add client data record to list.
  136.     if (status == noErr)
  137.     {
  138.         pNextAVTClientData = gpAVTFamilyData->pAVTClientList;
  139.         if (pNextAVTClientData != nil)
  140.             pNextAVTClientData->pPrevAVTClientData = pAVTClientData;
  141.  
  142.         pAVTClientData->pPrevAVTClientData = nil;
  143.         pAVTClientData->pNextAVTClientData = pNextAVTClientData;
  144.         gpAVTFamilyData->pAVTClientList = pAVTClientData;
  145.     }
  146.  
  147.     // Create client Apple Event queue.
  148.     if (status == noErr)
  149.         status = AVTCreateClientAppleEventQueue (pAVTClientData);
  150.  
  151.     // Create an Apple Event target descriptor for the client.
  152.     if (status == noErr)
  153.     {
  154.         status = GetCurrentProcess (¤tPSN);
  155.  
  156.         if (status == noErr)
  157.         {
  158.             status = AECreateDesc (typeProcessSerialNumber,
  159.                                    ¤tPSN,
  160.                                    sizeof (ProcessSerialNumber),
  161.                                    &(pAVTClientData->clientAEAddress));
  162.             if (status == noErr)
  163.                 pAVTClientData->clientAEAddressValid = true;
  164.         }
  165.     }
  166.  
  167.     // Create an Apple Event for device added notification.
  168.     if (status == noErr)
  169.     {
  170.         status = AECreateAppleEvent
  171.                     (kAEAVTransportEventClass,
  172.                      kAEAVTransportDeviceAdded,
  173.                      &(pAVTClientData->clientAEAddress),
  174.                      kAutoGenerateReturnID,
  175.                      kAnyTransactionID,
  176.                      &(pAVTClientData->deviceAddedAppleEvent));
  177.         if (status == noErr)
  178.             pAVTClientData->deviceAddedAppleEventValid = true;
  179.     }
  180.  
  181.     // Create an Apple Event for device removed notification.
  182.     if (status == noErr)
  183.     {
  184.         status = AECreateAppleEvent
  185.                     (kAEAVTransportEventClass,
  186.                      kAEAVTransportDeviceRemoved,
  187.                      &(pAVTClientData->clientAEAddress),
  188.                      kAutoGenerateReturnID,
  189.                      kAnyTransactionID,
  190.                      &(pAVTClientData->deviceRemovedAppleEvent));
  191.         if (status == noErr)
  192.             pAVTClientData->deviceRemovedAppleEventValid = true;
  193.     }
  194.  
  195.     // Clean up on error.
  196.     if (status != noErr)
  197.     {
  198.         if (avtClientID != kInvalidAVTClientID)
  199.             UnregisterAVTClientApplication (avtClientID);
  200.     }
  201.  
  202.     // Return results.
  203.     *pAVTClientID = avtClientID;
  204.  
  205.     return (status);
  206. }
  207.  
  208.  
  209. ////////////////////////////////////////////////////////////////////////////////
  210. //
  211. // UnregisterAVTClientApplication
  212. //
  213. //   This routine unregisters the calling application as a client of the
  214. // AV transport control driver family.
  215. //
  216.  
  217. OSStatus    UnregisterAVTClientApplication(
  218.     AVTClientID                    avtClientID)
  219. {
  220.     AVTClientDataPtr            pAVTClientData,
  221.                                 pPrevAVTClientData,
  222.                                 pNextAVTClientData;
  223.     OSStatus                    status = noErr;
  224.  
  225.     if (avtClientID != kInvalidAVTClientID)
  226.     {
  227.         // Get client data from ID.
  228.         pAVTClientData = (AVTClientDataPtr) avtClientID;
  229.  
  230.         // Deallocate device removed Apple Event.
  231.         if (pAVTClientData->deviceRemovedAppleEventValid)
  232.             AEDisposeDesc (&(pAVTClientData->deviceRemovedAppleEvent));
  233.  
  234.         // Deallocate device added Apple Event.
  235.         if (pAVTClientData->deviceAddedAppleEventValid)
  236.             AEDisposeDesc (&(pAVTClientData->deviceAddedAppleEvent));
  237.  
  238.         // Deallocate target descriptor.
  239.         if (pAVTClientData->clientAEAddressValid)
  240.             AEDisposeDesc (&(pAVTClientData->clientAEAddress));
  241.  
  242.         // Dispose of client Apple Event queue.
  243.         if (pAVTClientData->clientAppleEventQueue != nil)
  244.             AVTDisposeClientAppleEventQueue (pAVTClientData);
  245.  
  246.         // Remove client from list.
  247.         pPrevAVTClientData = pAVTClientData->pPrevAVTClientData;
  248.         pNextAVTClientData = pAVTClientData->pNextAVTClientData;
  249.  
  250.         if (pPrevAVTClientData != nil)
  251.             pPrevAVTClientData->pNextAVTClientData = pNextAVTClientData;
  252.         else
  253.             gpAVTFamilyData->pAVTClientList = pNextAVTClientData;
  254.  
  255.         if (pNextAVTClientData != nil)
  256.             pNextAVTClientData->pPrevAVTClientData = pPrevAVTClientData;
  257.  
  258.         // Deallocate client data record.
  259.         PoolDeallocate ((Ptr) pAVTClientData);
  260.     }
  261.  
  262.     return (status);
  263. }
  264.  
  265.  
  266. ////////////////////////////////////////////////////////////////////////////////
  267. //
  268. // GetAVTDriverList
  269. //
  270. //   This routine returns a list of AV transport control driver IDs and the
  271. // number of drivers installed in the system.
  272. //
  273.  
  274. OSStatus    GetAVTDriverList(
  275.     AVTDriverID                    *pAVTDriverIDList,
  276.     UInt32                        avtDriverIDListSize,
  277.     UInt32                        *pNumAVTDrivers)
  278. {
  279.     AVTDriverDataPtr            pAVTDriverData;
  280.     UInt32                        numAVTDrivers,
  281.                                 numAVTDriversInList,
  282.                                 driverNum;
  283.     OSStatus                    status = noErr;
  284.  
  285.     // Compute number of drivers to put in list.
  286.     numAVTDrivers = gpAVTFamilyData->numAVTDrivers;
  287.     numAVTDriversInList = avtDriverIDListSize;
  288.     if (numAVTDriversInList > numAVTDrivers)
  289.         numAVTDriversInList = numAVTDrivers;
  290.  
  291.     // Copy driver IDs in order.
  292.     pAVTDriverData = gpAVTFamilyData->pAVTDriverList;
  293.     for (driverNum = 0; driverNum < numAVTDriversInList; driverNum++)
  294.     {
  295.         pAVTDriverIDList[driverNum] = (AVTDriverID) pAVTDriverData;
  296.         pAVTDriverData = pAVTDriverData->pNextAVTDriverData;
  297.     }
  298.  
  299.     // Return number of installed drivers.
  300.     *pNumAVTDrivers = numAVTDrivers;
  301.  
  302.     return (status);
  303. }
  304.  
  305.  
  306. ////////////////////////////////////////////////////////////////////////////////
  307. //
  308. // CallAVTDriver
  309. //
  310. //   This routine sends a request to the given driver.
  311. //
  312.  
  313. OSStatus    CallAVTDriver(
  314.     AVTDriverID                    avtDriverID,
  315.     AVTInterfaceParamsPtr        pAVTInterfaceParams)
  316. {
  317.     AVTDriverDataPtr            pAVTDriverData;
  318.     CntrlParam                    cntrlParam;
  319.     OSStatus                    status = noErr;
  320.  
  321.     // Get the driver data from the ID.
  322.     pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  323.  
  324. /*zzz*/
  325.     if (pAVTDriverData->deviceDisconnected)
  326.         return (-139);//zzz need disconnectedErr
  327. /*zzz*/
  328.     // Set up control parameters.
  329.     cntrlParam.ioCompletion = nil;
  330.     cntrlParam.ioVRefNum = 0;
  331.     cntrlParam.ioCRefNum = pAVTDriverData->driverRefNum;
  332.     cntrlParam.csCode = cscAVTCommand;
  333.     *((Ptr *) &(cntrlParam.csParam[0])) = (Ptr) pAVTInterfaceParams;
  334.  
  335.     // Call the driver.
  336.     status = PBControlSync ((ParmBlkPtr) &cntrlParam);
  337.  
  338.     return (status);
  339. }
  340.  
  341.  
  342. ////////////////////////////////////////////////////////////////////////////////
  343. //
  344. // OpenAVTDriver
  345. //
  346. //   This routine opens a connection to the given driver.
  347. //
  348.  
  349. OSStatus    OpenAVTDriver (
  350.     AVTDriverID                    avtDriverID)
  351. {
  352.     AVTDriverDataPtr            pAVTDriverData;
  353.     OSStatus                    status = noErr;
  354.  
  355.     // Get the driver data from the ID.
  356.     pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  357.  
  358.     // One more connection.
  359.     pAVTDriverData->numConnections++;
  360.  
  361.     return (status);
  362. }
  363.  
  364.  
  365. ////////////////////////////////////////////////////////////////////////////////
  366. //
  367. // CloseAVTDriver
  368. //
  369. //   This routine closes a connection to the given driver.
  370. //
  371.  
  372. OSStatus    CloseAVTDriver (
  373.     AVTDriverID                    avtDriverID)
  374. {
  375.     AVTDriverDataPtr            pAVTDriverData;
  376.     OSStatus                    status = noErr;
  377.  
  378.     // Get the driver data from the ID.
  379.     pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  380.  
  381.     // One less connection.
  382.     pAVTDriverData->numConnections--;
  383.  
  384.     // Dispose driver if device has been disconnected.
  385.     if ((pAVTDriverData->deviceDisconnected) && (pAVTDriverData->numConnections == 0))
  386.         DisposeAVTDriver (avtDriverID);
  387.  
  388.     return (status);
  389. }
  390.  
  391.  
  392. ////////////////////////////////////////////////////////////////////////////////
  393. //
  394. // GetNextAVTClientEvent
  395. //
  396. //   This routine checks if any client Apple Events are pending and sends any
  397. // that are.
  398. //
  399.  
  400. OSStatus    GetNextAVTClientEvent(
  401.     AVTClientID                    avtClientID)
  402. {
  403.     AVTClientDataPtr            pAVTClientData;
  404.     ClientAppleEventDataPtr        pClientAppleEventData;
  405.     AppleEvent                    reply;
  406.     OSStatus                    status = noErr,
  407.                                 queueStatus = noErr;
  408.  
  409.     // Get client data from ID.
  410.     pAVTClientData = (AVTClientDataPtr) avtClientID;
  411.  
  412.     // Send any client Apple Events on queue.
  413.     while (queueStatus == noErr)
  414.     {
  415.         queueStatus = PBDequeueFirst (pAVTClientData->clientAppleEventQueue,
  416.                                       (QElemPtr *) &pClientAppleEventData);
  417.         if (queueStatus == noErr)
  418.         {
  419.             // Send the Apple Event.
  420.             AESend (&(pClientAppleEventData->clientAppleEvent),
  421.                     &reply,
  422.                     pClientAppleEventData->sendMode,
  423.                     pClientAppleEventData->sendPriority,
  424.                     pClientAppleEventData->timeOutInTicks,
  425.                     pClientAppleEventData->idleProc,
  426.                     pClientAppleEventData->filterProc);
  427.  
  428.             // Dispose of reply.
  429.             AEDisposeDesc (&reply);
  430.  
  431.             // We're now done with the client Apple Event data record.
  432.             DisposeClientAppleEventData (pClientAppleEventData);
  433.         }
  434.     }
  435.  
  436.     return (status);
  437. }
  438.  
  439.  
  440. ////////////////////////////////////////////////////////////////////////////////
  441. ////////////////////////////////////////////////////////////////////////////////
  442. //
  443. // Private routines.
  444. //
  445. ////////////////////////////////////////////////////////////////////////////////
  446. ////////////////////////////////////////////////////////////////////////////////
  447.  
  448. ////////////////////////////////////////////////////////////////////////////////
  449. //
  450. // InitializeAVTFamily
  451. //
  452. //   This routine initializes the AV transport control driver family.
  453. //
  454.  
  455. long    InitializeAVTFamily(void)
  456. {
  457.     OSStatus                    status = noErr;
  458.  
  459.     // Allocate family global record.
  460.     gpAVTFamilyData =
  461.         (AVTFamilyDataPtr) PoolAllocateResident (sizeof (AVTFamilyData), true);
  462.     if (gpAVTFamilyData == nil)
  463.         status = memFullErr;
  464.  
  465.     return ((long) status);
  466. }
  467.  
  468.  
  469. ////////////////////////////////////////////////////////////////////////////////
  470. //
  471. // TerminateAVTFamily
  472. //
  473. //   This routine terminates the AV transport control driver family.
  474. //
  475.  
  476. long    TerminateAVTFamily(void)
  477. {
  478.     OSStatus                    status = noErr;
  479.  
  480.     // Deallocate family global record.
  481.     if (gpAVTFamilyData != nil)
  482.         PoolDeallocate ((Ptr) gpAVTFamilyData);
  483.  
  484.     return ((long) status);
  485. }
  486.  
  487.  
  488. ////////////////////////////////////////////////////////////////////////////////
  489. //
  490. // InstallAVTExpert
  491. //
  492. //   This routine installs the AV transport control driver expert loading
  493. // mechanism.
  494. //
  495.  
  496. OSStatus    InstallAVTExpert(void)
  497. {
  498.     UInt32                        eventTable[1];
  499.     OSStatus                    status = noErr;
  500.  
  501.     // Register to receive generic device added events.
  502.     eventTable[0] = kGDFDeviceAddedEvent;
  503.     eventTable[1] = kGDFDeviceRemovedEvent;
  504.     status = GDFRegisterDeviceEventHandlerProc
  505.                 (kNdrvTypeIsAVTransport,
  506.                  2,
  507.                  &eventTable[0],
  508.                  AVTEventHandler,
  509.                  nil,
  510.                  &(gpAVTExpertData->gdfDeviceEventRegistrationID));
  511.  
  512.     return (status);
  513. }
  514.  
  515.  
  516. ////////////////////////////////////////////////////////////////////////////////
  517. //
  518. // UninstallAVTExpert
  519. //
  520. //   This routine uninstalls the AV transport control driver expert loading
  521. // mechanism.
  522. //
  523.  
  524. OSStatus    UninstallAVTExpert(void)
  525. {
  526.     OSStatus                    status = noErr;
  527.  
  528.     // Dispose of AVTExpert data.
  529.     if (gpAVTExpertData != nil)
  530.     {
  531.         // Unregister with Generic Device family.
  532.         if (gpAVTExpertData->gdfDeviceEventRegistrationID !=
  533.             kInvalidGDFDeviceEventRegistrationID)
  534.         {
  535.             status = GDFUnregisterDeviceEventHandler
  536.                         (gpAVTExpertData->gdfDeviceEventRegistrationID);
  537.         }
  538.  
  539.         PoolDeallocate ((Ptr) gpAVTExpertData);
  540.         gpAVTExpertData = nil;
  541.     }
  542.  
  543.     return (status);
  544. }
  545.  
  546.  
  547. ////////////////////////////////////////////////////////////////////////////////
  548. ////////////////////////////////////////////////////////////////////////////////
  549. //
  550. // Internal routines.
  551. //
  552. ////////////////////////////////////////////////////////////////////////////////
  553. ////////////////////////////////////////////////////////////////////////////////
  554.  
  555. ////////////////////////////////////////////////////////////////////////////////
  556. //
  557. // AVTEventHandler
  558. //
  559. //   This proc handles device events for AV transport devices.
  560. //
  561.  
  562. static OSStatus    AVTEventHandler(
  563.     GDFDeviceEventDataPtr        pGDFDeviceEventData)
  564. {
  565.     OSStatus                    status = noErr;
  566.  
  567.     // Dispatch off of device event.
  568.     switch (pGDFDeviceEventData->deviceEvent)
  569.     {
  570.         case kGDFDeviceAddedEvent :
  571.             status = AVTHandleDeviceAdded (pGDFDeviceEventData);
  572.             break;
  573.  
  574.         case kGDFDeviceRemovedEvent :
  575.             status = AVTHandleDeviceRemoved (pGDFDeviceEventData);
  576.             break;
  577.  
  578.         default :
  579.             break;
  580.     }
  581.  
  582.     return (status);
  583. }
  584.  
  585.  
  586. ////////////////////////////////////////////////////////////////////////////////
  587. //
  588. // AVTHandleDeviceAdded
  589. //
  590. //   This routine handles new devices being added.
  591. //
  592.  
  593. static OSStatus    AVTHandleDeviceAdded(
  594.     GDFDeviceEventDataPtr        pGDFDeviceEventData)
  595. {
  596.     AVTDriverID                    avtDriverID;
  597.     AVTDriverDataPtr            pAVTDriverData;
  598.  
  599.     AVTClientDataPtr            pAVTClientData;
  600.  
  601.     OSStatus                    status = noErr,
  602.                                 clientStatus;
  603.  
  604.     // Check if avt driver is in our list.  This will happen if device was
  605.     // connected, opened, disconnected, and reconnected without being closed.
  606.     // If it's in our list, set disconnected to false.
  607.     avtDriverID = AVTFindDriver (&(pGDFDeviceEventData->deviceRegEntryID));
  608.     if (avtDriverID != kInvalidAVTDriverID)
  609.     {
  610.         pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  611.         pAVTDriverData->deviceDisconnected = false;
  612.     }
  613.     else
  614.     {
  615.         status = AVTAddDriver (pGDFDeviceEventData, &avtDriverID);
  616.         if (status == noErr)
  617.             pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  618.     }
  619.  
  620.     // Send up notification to all clients.
  621.     if (status == noErr)
  622.     {
  623.         pAVTClientData = gpAVTFamilyData->pAVTClientList;
  624.         while (pAVTClientData != nil)
  625.         {
  626.             // Add the driver ID parameter to event.
  627.             clientStatus = AEPutParamPtr
  628.                             (&(pAVTClientData->deviceAddedAppleEvent),
  629.                              kAEAVTDriverIDKey,
  630.                              kAEAVTDriverIDType,
  631.                              &avtDriverID,
  632.                              sizeof (AVTDriverID));
  633.  
  634.             // Send event.
  635.             if (clientStatus == noErr)
  636.             {
  637.                 clientStatus = AVTSendClientAppleEvent
  638.                                 (pAVTClientData,
  639.                                  &(pAVTClientData->deviceAddedAppleEvent),
  640.                                  0,
  641.                                  kAENormalPriority,
  642.                                  0,
  643.                                  nil,
  644.                                  nil);
  645.             }
  646.  
  647.             pAVTClientData = pAVTClientData->pNextAVTClientData;
  648.         }
  649.     }
  650.  
  651.     return (status);
  652. }
  653.  
  654.  
  655. ////////////////////////////////////////////////////////////////////////////////
  656. //
  657. // AVTHandleDeviceRemoved
  658. //
  659. //   This routine handles devices being removed.
  660. //
  661.  
  662. static OSStatus    AVTHandleDeviceRemoved(
  663.     GDFDeviceEventDataPtr        pGDFDeviceEventData)
  664. {
  665.     RegEntryIDPtr                pRegEntryID;
  666.     AVTDriverID                    avtDriverID;
  667.     AVTDriverDataPtr            pAVTDriverData;
  668.     AVTClientDataPtr            pAVTClientData;
  669.     Boolean                        found;
  670.     OSStatus                    status = noErr,
  671.                                 clientStatus;
  672.  
  673.     // Get Name Registry entry.
  674.     pRegEntryID = &(pGDFDeviceEventData->deviceRegEntryID);
  675.  
  676.     // Find driver that is being removed.
  677.     avtDriverID = AVTFindDriver (pRegEntryID);
  678.     if (avtDriverID != kInvalidAVTDriverID)
  679.     {
  680.         pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  681.         found = true;
  682.     }
  683.     else
  684.     {
  685.         found = false;
  686.     }
  687.  
  688.     // If driver was found, set it disconnected.
  689.     if (found)
  690.         pAVTDriverData->deviceDisconnected = true;
  691.  
  692.     // Dispose driver if no one has it open.
  693.     // Otherwise, send up notification to all clients.
  694.     if (found)
  695.     {
  696.         if (pAVTDriverData->numConnections == 0)
  697.         {
  698.             DisposeAVTDriver ((AVTDriverID) pAVTDriverData);
  699.         }
  700.         else
  701.         {
  702.             pAVTClientData = gpAVTFamilyData->pAVTClientList;
  703.             while (pAVTClientData != nil)
  704.             {
  705.                 // Add the driver ID parameter to event.
  706.                 clientStatus = AEPutParamPtr
  707.                                 (&(pAVTClientData->deviceRemovedAppleEvent),
  708.                                  kAEAVTDriverIDKey,
  709.                                  kAEAVTDriverIDType,
  710.                                  &avtDriverID,
  711.                                  sizeof (AVTDriverID));
  712.  
  713.                 // Send event.
  714.                 if (clientStatus == noErr)
  715.                 {
  716.                     clientStatus = AVTSendClientAppleEvent
  717.                                     (pAVTClientData,
  718.                                      &(pAVTClientData->deviceRemovedAppleEvent),
  719.                                      0,
  720.                                      kAENormalPriority,
  721.                                      0,
  722.                                      nil,
  723.                                      nil);
  724.                 }
  725.  
  726.                 pAVTClientData = pAVTClientData->pNextAVTClientData;
  727.             }
  728.         }
  729.     }
  730.  
  731.     return (status);
  732. }
  733.  
  734.  
  735. ////////////////////////////////////////////////////////////////////////////////
  736. //
  737. // AVTSendClientAppleEvent
  738. //
  739. //   This routine queues an Apple Event to be sent to a client for device
  740. // notification.
  741. //
  742.  
  743. static OSErr    AVTSendClientAppleEvent(
  744.     AVTClientDataPtr            pAVTClientData,
  745.     const AppleEvent            *theAppleEvent,
  746.     AESendMode                    sendMode,
  747.     AESendPriority                sendPriority,
  748.     long                        timeOutInTicks,
  749.     AEIdleUPP                    idleProc,
  750.     AEFilterUPP                    filterProc)
  751. {
  752.     ClientAppleEventDataPtr        pClientAppleEventData = nil;    
  753.     OSErr                        err = noErr;
  754.  
  755.     // Create data for the client Apple Event.
  756.     pClientAppleEventData = (ClientAppleEventDataPtr)
  757.         PoolAllocateResident (sizeof (ClientAppleEventData), true);
  758.     if (pClientAppleEventData != nil)
  759.     {
  760.         pClientAppleEventData->sendMode =
  761.             (sendMode & ~(kAENoReply | kAEQueueReply | kAEWaitReply)) | kAENoReply;
  762.         pClientAppleEventData->sendPriority = sendPriority;
  763.         pClientAppleEventData->timeOutInTicks = timeOutInTicks;
  764.         pClientAppleEventData->idleProc = idleProc;
  765.         pClientAppleEventData->filterProc = filterProc;
  766.     }
  767.     else
  768.     {
  769.         err = memFullErr;
  770.     }
  771.  
  772.     // Copy the given Apple Event.
  773.     if (err == noErr)
  774.     {
  775.         err = AEDuplicateDesc (theAppleEvent,
  776.                                &(pClientAppleEventData->clientAppleEvent));
  777.         if (err == noErr)
  778.             pClientAppleEventData->clientAppleEventValid = true;
  779.     }
  780.  
  781.     // Queue the client Apple Event to be sent at a good time.
  782.     if (err == noErr)
  783.     {
  784.         err = PBEnqueueLast ((QElemPtr) pClientAppleEventData,
  785.                              pAVTClientData->clientAppleEventQueue);
  786.     }
  787.  
  788.     // Clean up on error.
  789.     if (err != noErr)
  790.         DisposeClientAppleEventData (pClientAppleEventData);
  791.  
  792.     return (err);
  793. }
  794.  
  795.  
  796. ////////////////////////////////////////////////////////////////////////////////
  797. //
  798. // DisposeClientAppleEventData
  799. //
  800. //   This routine disposes of the client Apple Event record.
  801. //
  802.  
  803. static void    DisposeClientAppleEventData(
  804.     ClientAppleEventDataPtr        pClientAppleEventData)
  805. {
  806.     if (pClientAppleEventData != nil)
  807.     {
  808.         // Dispose of Apple Event copy.
  809.         if (pClientAppleEventData->clientAppleEventValid)
  810.             AEDisposeDesc (&(pClientAppleEventData->clientAppleEvent));
  811.  
  812.         // Dispose of client Apple Event data record.
  813.         PoolDeallocate ((Ptr) pClientAppleEventData);
  814.     }
  815. }
  816.  
  817.  
  818. ////////////////////////////////////////////////////////////////////////////////
  819. //
  820. // AVTCreateClientAppleEventQueue
  821. //
  822. //   This routine creates a client AppleEvent queue.
  823. //
  824.  
  825. static OSStatus    AVTCreateClientAppleEventQueue(
  826.     AVTClientDataPtr            pAVTClientData)
  827. {
  828.     OSStatus                    status = noErr;
  829.  
  830.     status = PBQueueCreate (&(pAVTClientData->clientAppleEventQueue));
  831.  
  832.     return (status);
  833. }
  834.  
  835.  
  836. ////////////////////////////////////////////////////////////////////////////////
  837. //
  838. // AVTDisposeClientAppleEventQueue
  839. //
  840. //   This routine disposes of a client AppleEvent queue.
  841. //
  842.  
  843. static OSStatus    AVTDisposeClientAppleEventQueue(
  844.     AVTClientDataPtr            pAVTClientData)
  845. {
  846.     ClientAppleEventDataPtr        pClientAppleEventData;
  847.     OSStatus                    status = noErr;
  848.  
  849.     if (pAVTClientData->clientAppleEventQueue != nil)
  850.     {
  851.         // Dispose of any client AppleEvents still in queue.
  852.         while (status == noErr)
  853.         {
  854.             status = PBDequeueFirst (pAVTClientData->clientAppleEventQueue,
  855.                                      (QElemPtr *) &pClientAppleEventData);
  856.             if (status == noErr)
  857.                 DisposeClientAppleEventData (pClientAppleEventData);
  858.         }
  859.  
  860.         // Delete queue.
  861.         PBQueueDelete (pAVTClientData->clientAppleEventQueue);
  862.     }
  863.  
  864.     return (status);
  865. }
  866.  
  867.  
  868. ////////////////////////////////////////////////////////////////////////////////
  869. //
  870. // AVTAddDriver
  871. //
  872. //   This routine adds a new driver.
  873. //
  874.  
  875. static OSStatus    AVTAddDriver(
  876.     GDFDeviceEventDataPtr        pGDFDeviceEventData,
  877.     AVTDriverID                    *pAVTDriverID)
  878. {
  879.     RegEntryIDPtr                pRegEntryID;
  880.     AVTDriverID                    avtDriverID = kInvalidAVTDriverID;
  881.     AVTDriverDataPtr            pAVTDriverData;
  882.  
  883.     OSStatus                    status = noErr;
  884.  
  885.     // Get Name Registry entry.
  886.     pRegEntryID = &(pGDFDeviceEventData->deviceRegEntryID);
  887.  
  888.     // Add AV transport control driver record to list.
  889.     if (status == noErr)
  890.         status = CreateAVTDriverID (&avtDriverID);
  891.  
  892.     // Get the driver data from the ID.
  893.     if (status == noErr)
  894.         pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  895.  
  896.     // Fill in driver data record.
  897.     if (status == noErr)
  898.     {
  899.         pAVTDriverData->deviceRegistryID = *pRegEntryID;
  900.         pAVTDriverData->driverRefNum = pGDFDeviceEventData->driverRefNum;
  901.     }
  902.  
  903.     // Open driver.
  904.     if (status == noErr)
  905.     {
  906.         status = OpenInstalledDriver (pGDFDeviceEventData->driverRefNum, fsRdWrPerm);
  907.         if (status == noErr)
  908.             pAVTDriverData->driverOpened = true;
  909.     }
  910.  
  911.     // Clean up on error.
  912.     if (status != noErr)
  913.     {
  914.         if (avtDriverID != kInvalidAVTDriverID)
  915.             DisposeAVTDriver (avtDriverID);
  916.     }
  917.  
  918.     // Return results.
  919.     if (status == noErr)
  920.         *pAVTDriverID = avtDriverID;
  921.     else
  922.         *pAVTDriverID = kInvalidAVTDriverID;
  923.  
  924.     return (status);
  925. }
  926.  
  927.  
  928. ////////////////////////////////////////////////////////////////////////////////
  929. //
  930. // CreateAVTDriverID
  931. //
  932. //   This routine creates a new AV transport control driver record, adds it to
  933. // the family list, and returns the ID for the new driver record.
  934. //
  935.  
  936. static OSStatus    CreateAVTDriverID(
  937.     AVTDriverID                    *pAVTDriverID)
  938. {
  939.     AVTDriverDataPtr            pAVTDriverData = nil,
  940.                                 pNextAVTDriverData;
  941.     OSStatus                    status = noErr;
  942.  
  943.     // Allocate AV transport control driver record.
  944.     pAVTDriverData = (AVTDriverDataPtr)
  945.         PoolAllocateResident (sizeof (AVTDriverData), true);
  946.     if (pAVTDriverData != nil)
  947.         pAVTDriverData->avtDriverID = (AVTDriverID) pAVTDriverData;
  948.     else
  949.         status = memFullErr;
  950.  
  951.     // Add driver record to family list.
  952.     if (status == noErr)
  953.     {
  954.         pNextAVTDriverData = gpAVTFamilyData->pAVTDriverList;
  955.         pAVTDriverData->pNextAVTDriverData = pNextAVTDriverData;
  956.         gpAVTFamilyData->pAVTDriverList = pAVTDriverData;
  957.         gpAVTFamilyData->numAVTDrivers++;
  958.     }
  959.  
  960.     // Return result and clean up on error.
  961.     if (status == noErr)
  962.     {
  963.         *pAVTDriverID = pAVTDriverData->avtDriverID;
  964.     }
  965.     else
  966.     {
  967.         if (pAVTDriverData != nil)
  968.             PoolDeallocate ((Ptr) pAVTDriverData);
  969.  
  970.         *pAVTDriverID = kInvalidAVTDriverID;
  971.     }
  972.  
  973.     return (status);
  974. }
  975.  
  976.  
  977. ////////////////////////////////////////////////////////////////////////////////
  978. //
  979. // DisposeAVTDriver
  980. //
  981. //   This routine disposes of the given driver.  It will call the driver to
  982. // terminate itself, dispose of the driver memory closure, remove the driver
  983. // data record from our list, and dispose of the driver data record.
  984. //
  985.  
  986. static void    DisposeAVTDriver(
  987.     AVTDriverID                    avtDriverID)
  988. {
  989.     AVTDriverDataPtr            pAVTDriverData,
  990.                                 pSearchAVTDriverData,
  991.                                 pPrevAVTDriverData;
  992.     THz                            currentZone;
  993.  
  994.     // Switch to system zone.
  995.     currentZone = GetZone ();
  996.     SetZone (SystemZone ());
  997.  
  998.     // Get the driver data from the ID.
  999.     pAVTDriverData = (AVTDriverDataPtr) avtDriverID;
  1000.  
  1001.     // Close the driver.
  1002.     if (pAVTDriverData->driverOpened)
  1003.         CloseDriver (pAVTDriverData->driverRefNum);
  1004.  
  1005.     // Remove driver record from family list.
  1006.     pSearchAVTDriverData = gpAVTFamilyData->pAVTDriverList;
  1007.     pPrevAVTDriverData = nil;
  1008.     while ((pSearchAVTDriverData != nil) &&
  1009.            (pSearchAVTDriverData != pAVTDriverData))
  1010.     {
  1011.         pPrevAVTDriverData = pSearchAVTDriverData;
  1012.         pSearchAVTDriverData =
  1013.             pSearchAVTDriverData->pNextAVTDriverData;
  1014.     }
  1015.     if (pSearchAVTDriverData != nil)
  1016.     {
  1017.         if (pPrevAVTDriverData != nil)
  1018.         {
  1019.             pPrevAVTDriverData->pNextAVTDriverData =
  1020.                 pAVTDriverData->pNextAVTDriverData;
  1021.         }
  1022.         else
  1023.         {
  1024.             gpAVTFamilyData->pAVTDriverList =
  1025.                 pAVTDriverData->pNextAVTDriverData;
  1026.         }
  1027.     }
  1028.     gpAVTFamilyData->numAVTDrivers--;
  1029.  
  1030.     // Deallocate driver data record.
  1031.     PoolDeallocate ((Ptr) pAVTDriverData);
  1032.  
  1033.     // Switch zone back.
  1034.     SetZone (currentZone);
  1035. }
  1036.  
  1037.  
  1038. ////////////////////////////////////////////////////////////////////////////////
  1039. //
  1040. // AVTFindDriver
  1041. //
  1042. //   This routine finds the AVT driver corresponding to the given Name Registry
  1043. // entry.
  1044. //
  1045.  
  1046. static AVTDriverID    AVTFindDriver(
  1047.     RegEntryIDPtr                pRegEntryID)
  1048. {
  1049.     AVTDriverID                    avtDriverID;
  1050.     AVTDriverDataPtr            pAVTDriverData;
  1051.     Boolean                        found;
  1052.  
  1053.     // Find driver that has matching name registry entry.
  1054.     pAVTDriverData = gpAVTFamilyData->pAVTDriverList;
  1055.     found = false;
  1056.     while ((pAVTDriverData != nil) && (!found))
  1057.     {
  1058.         if (RegistryEntryIDCompare (&(pAVTDriverData->deviceRegistryID), pRegEntryID))
  1059.             found = true;
  1060.         else
  1061.             pAVTDriverData = pAVTDriverData->pNextAVTDriverData;
  1062.     }
  1063.  
  1064.     // Set return value.
  1065.     if (found)
  1066.         avtDriverID = (AVTDriverID) pAVTDriverData;
  1067.     else
  1068.         avtDriverID = kInvalidAVTDriverID;
  1069.  
  1070.     return (avtDriverID);
  1071. }
  1072.